/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package tuplegenerator;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

/**
 *
 *
 */
public class TupleGenerator implements Runnable {

    public static final int UNIQUE_TUPLES = 100;
    private Random r = new Random();
    private ArrayList<SingleTuple> meterList = new ArrayList<SingleTuple>();
    private HashMap<Integer, MeterUser> meteruserList = new HashMap<Integer, MeterUser>();

    private boolean outsystem = false;
    
    public TupleGenerator() {
    	
    }
    
    public TupleGenerator(boolean outsystem) {
    	this.outsystem = outsystem;
    }
    
    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
        Thread t = new Thread(new TupleGenerator());
        t.start();
    }

    @Override
    public void run() {
        int n = 0;
        //long cnt = 0;

        try {
            PrintWriter writer = new PrintWriter(System.out);
            Socket client = new Socket(InetAddress.getByName("127.0.0.1"), 5555);
            Socket ulist = new Socket(InetAddress.getByName("127.0.0.1"), 5556);

            BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
            PrintWriter wrsock = new PrintWriter(client.getOutputStream(), true);
            PrintWriter ulistsock = new PrintWriter(ulist.getOutputStream(), true);

            String response = null;

            while (true) {

                response = reader.readLine();
                
                System.out.println("Response#: " + response);
                
                if (response == null || response.length() == 0) {
                    break;
                }
                if (response.equalsIgnoreCase("quit")) {
                    break;
                }
                
                
                int ts = Integer.parseInt(response);

                for (int i = 0; i < ts; i++) {
                    int mid = this.genMeterID();
                    double ap = this.genDouble(3, 7);
                    double rp = this.genDouble(0, 1);
                    double v = this.genDouble(220, 245);
                    double c = this.genDouble(13, 27);

                    SingleTuple tuple = new SingleTuple(mid, ap, rp, v, c);

                    MeterUser mu = null;
                    if (this.meterList.size() >= UNIQUE_TUPLES) {
                        mu = this.meteruserList.get(mid);
                    } else {
                        mu = new MeterUser(mid, this.genString(10));
                        this.meteruserList.put(mid, mu);
                    }

                    String text = tuple.toString();
                    if (outsystem) {
                    	writer.println(text);
                    }

                    wrsock.println(text);
                    ulistsock.println(mu.toString());

                    if (++n == 100) {
                        wrsock.flush();
                        ulistsock.flush();
                        n = 0;
                    }


                }

            }

            System.out.println("Sending completed!");
            wrsock.close();
            ulistsock.close();
            client.close();

        } catch (UnknownHostException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }

    }

    private int genMeterID() {
        if (meterList.size() >= UNIQUE_TUPLES) {
            int index = r.nextInt(meterList.size());
            return this.meterList.get(index).getMeterID();
        }

        int id = r.nextInt(10);
        int p = 10;
        for (int i = 1; i <= 6; i++) {
            int tmp = r.nextInt(10);
            id += p * tmp;
            p *= 10;
        }
        int tmp = r.nextInt(9) + 1;
        id += p * tmp;
        return id;
    }

    private String genString(int length) {

        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < length; i++) {
            int p = r.nextInt(26) + 65;
            sb.append((char) p);
        }

        return sb.toString();

    }

    private double genDouble(int limitMin, int limitHigh) {
        double dec = r.nextDouble();
        int d = r.nextInt(limitHigh - limitMin) + limitMin;
        return d + dec;
    }
}
